// $URL: http://mingw-lib.googlecode.com/svn/trunk/local/box/yt_new/yt_rec.h $
// $Rev: 791 $
// $Author: akio.miyoshi $
// $Date:: 2012-10-23 08:18:20 +0000#$

#ifndef YT_REC_H
#define YT_REC_H

#include <QtCore>
////#include <QtScript>
#include <QtSql>
#include "batchnetworkaccessmanager.h"

class RecPlaylist;
class T_Video;

class T_Video : public QObject {
	Q_OBJECT
public:
	T_Video(QObject *parent = 0);

	Q_PROPERTY(bool deleted READ get_deleted)
	bool deleted;
	qint32 get_deleted() const { return deleted; }

	Q_PROPERTY(qint32 pos READ get_pos WRITE set_pos)
	qint32 pos;
	qint32 get_pos() const { return pos; }
	void set_pos(qint32 a) { pos = a; }

	Q_PROPERTY(qint32 page READ get_page WRITE set_page)
	qint32 page;
	qint32 get_page() const { return page; }
	void set_page(qint32 a) { page = a; }

	Q_PROPERTY(QString guid READ get_guid WRITE set_guid)
	QString guid;
	QString get_guid() const { return guid; }
	void set_guid(QString a) { guid = a; }

	Q_PROPERTY(QString id READ get_id WRITE set_id)
	QString id;
	QString get_id() const { return id; }
	void set_id(QString a) { id = a; }

    Q_PROPERTY(QString self READ get_self WRITE set_self)
    QString self;
    QString get_self() const { return self; }
    void set_self(QString a) { self = a; }

	Q_PROPERTY(QString title READ get_title WRITE set_title)
	QString title;
	QString get_title() const { return title; }
	void set_title(QString a) { title = a; }

	Q_PROPERTY(QString author READ get_author WRITE set_author)
	QString author;
	QString get_author() const { return author; }
	void set_author(QString a) { author = a; }

    Q_PROPERTY(QString author_uri READ get_author_uri WRITE set_author_uri)
    QString author_uri;
    QString get_author_uri() const { return author_uri; }
    void set_author_uri(QString a) { author_uri = a; }

    Q_PROPERTY(QString author_id READ get_author_id WRITE set_author_id)
    QString author_id;
    QString get_author_id() const { return author_id; }
    void set_author_id(QString a) { author_id = a; }

    Q_PROPERTY(QDateTime pubdate READ get_pubdate WRITE set_pubdate)
	QDateTime pubdate;
	QDateTime get_pubdate() const { return pubdate; }
	void set_pubdate(QDateTime a) { pubdate = a; }

	Q_PROPERTY(qint32 view_count READ get_view_count WRITE set_view_count)
	qint32 view_count;
	qint32 get_view_count() const { return view_count; }
	void set_view_count(qint32 a) { view_count = a; }

	Q_PROPERTY(qint32 view_count_old READ get_view_count_old WRITE set_view_count_old)
	qint32 view_count_old;
	qint32 get_view_count_old() const { return view_count_old; }
	void set_view_count_old(qint32 a) { view_count_old = a; }

	Q_PROPERTY(qint32 view_rank READ get_view_rank WRITE set_view_rank)
	qint32 view_rank;
	qint32 get_view_rank() const { return view_rank; }
	void set_view_rank(qint32 a) { view_rank = a; }

	Q_PROPERTY(QDateTime view_ts READ get_view_ts WRITE set_view_ts)
	QDateTime view_ts;
	QDateTime get_view_ts() const { return view_ts; }
	void set_view_ts(QDateTime a) { view_ts = a; }

	Q_PROPERTY(QDateTime view_ts_old READ get_view_ts_old WRITE set_view_ts_old)
	QDateTime view_ts_old;
	QDateTime get_view_ts_old() const { return view_ts_old; }
	void set_view_ts_old(QDateTime a) { view_ts_old = a; }

	Q_PROPERTY(double view_ts_hour READ get_view_ts_hour)
	double get_view_ts_hour() const
	{
		if(!view_ts.isValid() || !view_ts_old.isValid()) return 0;
		int v_sec = view_ts_old.secsTo(view_ts);
		double v_hour = ((double)v_sec)/3600;
		return v_hour;
	}

	Q_PROPERTY(QString view_ts_diff READ get_view_ts_diff)
	QString get_view_ts_diff() const
	{
		if(!view_ts.isValid() || !view_ts_old.isValid()) return "";
		double v_hour = get_view_ts_hour();
#if 0x0
		int v_sec = view_ts_old.secsTo(view_ts);
		double v_hour = ((double)v_sec)/3600;
#endif
		//return QString("@%1h").arg(v_hour);
		//return QString("@%1s").arg(v_sec);
		QString v_result;
		v_result.sprintf("@%0.1fh", v_hour);
		return v_result;
	}

	Q_PROPERTY(qint32 view_rank_old READ get_view_rank_old WRITE set_view_rank_old)
	qint32 view_rank_old;
	qint32 get_view_rank_old() const { return view_rank_old; }
	void set_view_rank_old(qint32 a) { view_rank_old = a; }

	Q_PROPERTY(qint32 favorite_count READ get_favorite_count WRITE set_favorite_count)
	qint32 favorite_count;
	qint32 get_favorite_count() const { return favorite_count; }
	void set_favorite_count(qint32 a) { favorite_count = a; }

	Q_PROPERTY(qint32 favorite_count_old READ get_favorite_count_old WRITE set_favorite_count_old)
	qint32 favorite_count_old;
	qint32 get_favorite_count_old() const { return favorite_count_old; }
	void set_favorite_count_old(qint32 a) { favorite_count_old = a; }

	Q_PROPERTY(qint32 view_count_diff READ get_view_count_diff)
	qint32 get_view_count_diff() const
	{
		if(view_count_old < 0) return 0;
		return view_count - view_count_old;
	}

	Q_PROPERTY(qint32 favorite_count_diff READ get_favorite_count_diff)
	qint32 get_favorite_count_diff() const
	{
		if(favorite_count_old < 0) return 0;
		return favorite_count - favorite_count_old;
	}

	Q_PROPERTY(QString icon_url READ get_icon_url)
	QString get_icon_url() const;

	Q_PROPERTY(QString rank_diff_mark READ get_rank_diff_mark)
	QString get_rank_diff_mark() const
	{
		QString v_rank_diff = "";
		if(view_rank == view_rank_old) v_rank_diff = "→";
		else if(view_rank > view_rank_old) v_rank_diff = "↓";
		else v_rank_diff = "↑";
		return v_rank_diff;
	}

	QString toJSON() const;

	friend QDebug operator<< (QDebug d, const T_Video *model)
	{
		operator <<(d, (*model));
		return d;
	}

	friend QDebug operator<< (QDebug d, const T_Video &model)
	{
		d << "{T_Video:";
		d << "\n";
		for(int i=0; i<model.metaObject()->propertyCount(); i++)
		{
			QMetaProperty v_prop = model.metaObject()->property(i);
			if(strcmp(v_prop.name(), "objectName")==0) continue;
			d << QString("<%1>").arg(v_prop.name()) << model.property(v_prop.name());
			d << "\n";
		}
		d << "}";
		return d;
	}
};
////Q_SCRIPT_DECLARE_QMETAOBJECT(T_Video, QObject*)

class T_VideoList : public QObject {
	Q_OBJECT
public:
	T_VideoList(QObject *parent = 0): QObject(parent)
			, m_sort_type("unit_delta")
			, m_domain("")
	{

	}
	QList<T_Video *> m_list;
	void sort_internal(QString a_type);
	//
	Q_PROPERTY(QString sort_type READ get_sort_type)
	QString m_sort_type;
	QString get_sort_type() const { return m_sort_type; }
	//
	Q_PROPERTY(QString keyword READ get_keyword WRITE set_keyword)
	QString m_keyword;
	QString get_keyword() const { return m_keyword; }
	void set_keyword(QString a) {
		qDebug() << "T_VideoList::set_keyword()" << a;
		m_keyword = a;
	}
	//
	Q_PROPERTY(QString domain READ get_domain WRITE set_domain)
	QString m_domain;
	QString get_domain() const { return m_domain; }
	void set_domain(QString a);
	//
	Q_PROPERTY(QString tbl_name READ get_tbl_name)
	QString get_tbl_name() const
	{
		if(m_domain.isEmpty()) return "tbl_yt";
		QString v_tbl_name = m_domain;
		v_tbl_name.replace(":", "_");
		return v_tbl_name;
	}
public slots:
	int size() { return m_list.size(); }
	void clear();
	T_Video *append();
	void append(T_VideoList *a_video_list);
	T_Video *value(int index) { return m_list.value(index); }
	QString json(int index) { return m_list.value(index)->toJSON(); }
	T_Video *select(QString a_id)
	{
		for(int i=0; i<m_list.size(); i++)
		{
			if(m_list.value(i)->id == a_id) return m_list.value(i);
		}
		return NULL;
	}
	QVariant get_field(int index, QString name) const { return m_list.value(index)->property(name.toLatin1().constData()); }
	void sort(QString a_type);
	void update() { emit updated(); }
	void reload();
    void reload2();
    void deleteById(QString a_id);
public: signals:
	void sig_sort_spec(QString a_type);
	void updated();
};

class YtManager {
private:
    BatchNetworkAccessManager *m_nam;
public:
    YtManager(BatchNetworkAccessManager *a_nam): m_nam(a_nam) { }
    QDateTime parseDateTimeYoutube(QString pubDateStr);
    int parseXmlForPlaylistList(QByteArray &xml, QList<RecPlaylist> &result);
    int parseXmlForEntryList(QByteArray &xml, T_VideoList *result, qint64 *totalResultCount = 0, bool resolveUserName = false);
	void listUsersFavoriteWeb(QString a_user, T_VideoList *a_result);
	void listPlaylistVideoWeb(QString a_playlist_id, T_VideoList *a_result);
	bool dbVideoExists(QString a_id, QString a_tbl_name);
	void dbVideoInsert(T_Video * a_rec, QString a_tbl_name);
	void dbVideoDelete(QString a_id, QString a_tbl_name);
	static void dbVideoListLoad(T_VideoList *a_result, QString a_tbl_name, QString a_keyword);
	static bool dbVideoSelect(QString a_id, QString a_tbl_name, T_Video *a_rec);
	static void dbPrepareTable(QString a_tbl_name)
	{
		QSqlQuery v_query;
		QString v_sql = QString(
				"create table %1("
                " id text"
                ",self text"
                ",page long"
				",pos long"
				",title text"
                ",author text"
                ",author_uri text"
                ",author_id text"
                ",pubdate datetime"
				",view_count long"
				",view_rank long"
				",view_ts datetime"
				",favorite_count long"
				",primary key(pos,id)"
				")"
				).arg(a_tbl_name)
				;
		qDebug() << v_sql;
		v_query.exec(v_sql);
	}
};

class RecPlaylist {
public:
    QString guid;
    QString id;
    QString title;
    QDateTime published;
    friend QDebug operator<< (QDebug d, const RecPlaylist &model)
    {
        d << "{RecPlaylist:";
        d << "\n";
        d << "<guid>" << model.guid;
        d << "\n";
        d << "<id>" << model.id;
        d << "\n";
        d << "<title>" << model.title;
        d << "\n";
        d << "<published>" << model.published;
        d << "\n";
        d << "}";
        return d;
    }
};

#endif // YT_REC_H
